<template>
  <div style="margin: 10px; width: calc(100% - 20px); height: calc(100% - 20px)">
    <el-container style="height: 100%; background-color: #fff">
      <el-header class="header">
        <div class="title">鹿鲸基础物料制作</div>
        <div>
          <el-space>
            <el-button type="success" size="small" @click="onPreview">预览</el-button>
            <el-button type="primary" size="small" @click="onSave">保存</el-button>
            <el-button type="warning" size="small">发布</el-button>
          </el-space>
        </div>
      </el-header>
      <el-container>
        <div style="display: flex; width: 100%; flex: 1" class="code-tabs">
          <div style="width: 50%; height: 100%; border-right: 1px solid var(--el-menu-border-color)">
            <component :ref="componentId" :is="data.remote" v-if="data.remote"> </component>
          </div>
          <el-tabs v-model="activeName" style="width: calc(50% - 1px); height: 100%">
            <el-tab-pane label="Html" name="VueCode">
              <basic-editor ref="htmlRef" v-model="html"></basic-editor>
            </el-tab-pane>
            <el-tab-pane label="TypeScript" name="TSCode">
              <basic-editor ref="tsRef"></basic-editor>
            </el-tab-pane>
            <el-tab-pane label="Css" name="CssCode">
              <basic-editor ref="cssRef"></basic-editor>
            </el-tab-pane>
            <el-tab-pane label="Meta" name="Meta">
              <basic-editor></basic-editor>
            </el-tab-pane>
            <el-tab-pane label="Json示例" name="DemoConfig">
              <div style="height: 32px; padding-left: 20px">
                <el-radio-group v-model="jsonMode" size="small">
                  <el-radio-button label="代码面板" value="jsonCode" />
                  <el-radio-button label="可视化配置" value="jsonConfig" />
                  <el-radio-button label="JSON可视化" value="jsonViewer" disabled />
                </el-radio-group>
                <!-- <el-checkbox-group v-model="checkedValue" :min="1">
                  <el-checkbox
                    v-for="item in checkList"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                  >
                    {{ item.label }}
                  </el-checkbox>
                </el-checkbox-group> -->
              </div>
              <basic-editor ref="jsonRef" style="height: calc(100% - 36px)"></basic-editor>
            </el-tab-pane>
          </el-tabs>
        </div>
      </el-container>
    </el-container>
  </div>
</template>

<script lang="ts" setup>
import * as Vue from 'vue';
import { onMounted, reactive, ref } from 'vue';
import BasicEditor from '@/components/code-editor/basic-editor/index.vue';
import { loadModule } from 'vue3-sfc-loader/dist/vue3-sfc-loader.js';
import { dwHttp } from '@/utils/http';
defineOptions({
  name: 'BasicMaterialEditor',
});
const htmlRef = ref();
const tsRef = ref();
const cssRef = ref();
const jsonRef = ref();
const html = ref<string>('');
const componentId: never = Vue.useId() as never;
const activeName = ref<string>('VueCode');
const jsonMode = ref('jsonCode');
// const checkList = [
//   { label: '代码面板', value: 'code' },
//   { label: 'JSON可视化', value: 'viewer' },
//   { label: '可视化配置', value: 'config' },
// ]
const fullCode = ref<string>('<template><div></div></template>');
interface IBasicMaterialPreview {
  type: 'BASIC_MATERIAL' | 'COMPOSITE_MATERIAL';
  html: string;
  typescript: string;
  css: string;
  json: string;
}
const data = reactive({
  remote: null,
  temp: '',
  options: {
    moduleCache: {
      vue: Vue,
    },
    //获取文件
    async getFile(componentName: string) {
      console.log(componentName);
      return Promise.resolve(fullCode.value);
    },
    //添加样式
    addStyle(textContent: string) {
      console.log(textContent);
      const style = Object.assign(document.createElement('style'), {
        textContent,
      });
      const styleRef = document.head.getElementsByTagName('style')[0] || null;
      document.head.insertBefore(style, styleRef);
    },
  },
});

const onPreview = () => {
  const codeData: IBasicMaterialPreview = {
    type: 'BASIC_MATERIAL',
    html: ``,
    typescript: ``,
    css: ``,
    json: '{}',
  };

  const socket = new WebSocket(`ws://${window.location.host}:${window.location.port}/admin-api/websocket/2234234`);
  socket.onopen = () => {
    codeData.html = `<template>${htmlRef.value.getValue()}</template>`;
    codeData.typescript = `<script lang="ts" setup>${tsRef.value.getValue()}<\/script>`;
    codeData.css = `<style scoped>${cssRef.value.getValue()}</style>`;
    codeData.json = jsonRef.value.getValue();
    socket.send(JSON.stringify(codeData));
  };

  socket.onmessage = async (ev: MessageEvent) => {
    console.log(ev.data);
    fullCode.value = ev.data; //ev.data
    const component = await loadModule(new Date().toString() + '.vue', data.options);
    data.remote = component;
  };
  socket.close = () => {};
  socket.onerror = () => {};
};
interface IMaterialDefinition {
  id?: string;
  materialName: string;
  html: string;
  javascript: string;
  css: string;
  meta: string;
  jsonSchema: string;
  materialComemnt: string;
}
const onSave = () => {
  const data: IMaterialDefinition = {
    id: 'f75d18f7-b8c7-4d86-a906-7b592ef5e39c',
    materialName: 'dwForm',
    html: `${htmlRef.value.getValue()}`,
    javascript: `${tsRef.value.getValue()}`,
    css: `${cssRef.value.getValue()}`,
    meta: '',
    jsonSchema: jsonRef.value.getValue(),
    materialComemnt: '表单录入组件',
  };
  dwHttp({
    method: 'put',
    url: '/admin-api/material/definition',
    data: data,
  });
};

onMounted(() => {
  // dwHttp({
  //   method: 'get',
  //   isSuccessTip: false,
  //   url: '/admin-api/material/definition/f75d18f7-b8c7-4d86-a906-7b592ef5e39c',
  // }).then((res: { data: Record<string, string> }) => {
  //   htmlRef.value.setValue(res.data.html)
  //   cssRef.value.setValue(res.data.css)
  //   tsRef.value.setValue(res.data.javascript)
  //   jsonRef.value.setValue(res.data.jsonSchema)
  // })
});
</script>

<style lang="scss" scoped>
.header {
  border-bottom: 1px solid var(--el-border-color);
  height: 38px;
  display: flex;
  justify-content: space-between;
  justify-items: center;
  align-items: center;
  .title {
    font-size: 15px;
    font-weight: bold;
    color: var(--el-color-primary);
  }
}
.main {
  padding: 0;
}
.right {
  width: 280px;
  border-left: 1px solid var(--el-border-color);
}
.code-tabs :deep(.el-tabs__nav) {
  padding: 0 20px;
}
.code-tabs :deep(.el-tab-pane) {
  height: 100%;
}
.code-tabs :deep(.el-tabs__content) {
  height: 100%;
}
.code-tabs :deep(.el-tabs__header) {
  margin: 0;
}
.code-tabs :deep(.el-tabs__active-bar) {
  height: 3px;
}
</style>
